#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <queue>
#include <string>
#include <unordered_map>
#include <vector>

// PAT A 1072 Gas Station

struct Edge {
    int to;
    int dist;

    Edge(int to, int dist) : to(to), dist(dist) {}
};

struct Vertex {
    int index;
    std::string name;
    std::vector<Edge> edges;
    int dist;

    Vertex() {}
};

struct Solution {
    int startIdx;
    double minDist, avgDist;

    Solution(int startIdx, double minDist = 0, double avgDist = 0)
        : startIdx(startIdx), minDist(minDist), avgDist(avgDist) {}

    bool operator<(const Solution &other) const {
        if (minDist != other.minDist) return minDist > other.minDist;
        if (avgDist != other.avgDist) return avgDist < other.avgDist;
        return startIdx < other.startIdx;
    }
};

int nHouses, nStations, nVerts, range;
std::unordered_map<std::string, int> nameIdxMap;
std::vector<Vertex> vertices;  // [houses, stations]

struct Cmp {
    bool operator()(Vertex *u, Vertex *v) const {
        return u->dist > v->dist;
    }
};

Solution solve(int startIdx) {
    // Initialize
    std::priority_queue<Vertex *, std::deque<Vertex *>, Cmp> heap;
    Vertex *startVert = &vertices[startIdx];
    heap.push(startVert);
    for (int i = 0; i < nVerts; i++)
        vertices[i].dist = INT32_MAX;
    startVert->dist = 0;

    // Run algorithm
    while (!heap.empty()) {
        // Pick one vertex from queue
        Vertex *vert = heap.top();
        heap.pop();

        // Update neighbor distances
        for (int i = 0; i < vert->edges.size(); i++) {
            Edge &edge = vert->edges[i];
            Vertex *other = &vertices[edge.to];
            int newDist = vert->dist + edge.dist;
            if (newDist < other->dist) {
                other->dist = newDist;
                heap.push(other);
            }
        }
    }

    // Summarize distances
    bool valid = true;
    int minDist = INT32_MAX, maxDist = 0;
    int total = 0;
    for (int i = 0; i < nHouses; i++) {
        if (vertices[i].dist != INT32_MAX) {  // not even connected
            valid = false;
            break;
        }
        minDist = std::min(minDist, vertices[i].dist);
        maxDist = std::max(maxDist, vertices[i].dist);
        total += vertices[i].dist;
    }
    if (maxDist > range) valid = false;

    return valid ? Solution(startIdx, minDist, double(total) / nHouses)
                 : Solution(-1);
}

int main() {
    // Read graph
    int nRoads;
    scanf("%d %d %d %d", &nHouses, &nStations, &nRoads, &range);
    nVerts = nHouses + nStations;
    vertices = std::vector<Vertex>(nVerts);
    for (int i = 0; i < nHouses; i++) {
        std::string name = std::to_string(i + 1);
        vertices[i].name = name;
        vertices[i].index = i;
        nameIdxMap.insert(std::pair<std::string, int>(name, i));
    }
    for (int i = nHouses; i < nVerts; i++) {
        int stationIdx = i - nHouses + 1;
        std::string name = "G" + std::to_string(stationIdx);
        vertices[i].name = name;
        vertices[i].index = i;
        nameIdxMap.insert(std::pair<std::string, int>(name, i));
    }
    for (int i = 0; i < nRoads; i++) {
        std::string fromStr, toStr;
        int dist;
        std::cin >> fromStr >> toStr >> dist;
        int fromIdx = nameIdxMap[fromStr];
        int toIdx = nameIdxMap[toStr];
        vertices[fromIdx].edges.push_back(Edge(toIdx, dist));
        vertices[toIdx].edges.push_back(Edge(fromIdx, dist));
    }

    // Use Dijkstra algorithm to find shortest distances to houses
    std::vector<Solution> solutions;
    for (int i = nHouses; i < nVerts; i++) {
        Solution sol = solve(i);
        if (sol.startIdx < 0) continue;  // not a solution
        solutions.push_back(sol);
    }

    // Check solutions
    if (solutions.empty()) {
        printf("No Solution\n");
    } else {
        std::sort(solutions.begin(), solutions.end());
        Solution &best = solutions[0];
        printf("%s\n%.1f %.1f\n", vertices[best.startIdx].name.c_str(),
               best.minDist, best.avgDist);
    }

    return 0;
}